package com.tom.architect02.mnbase.annotation.apt.compiler;

//import com.example.annotations.BindView;
//import com.google.auto.service.AutoService;
//import com.google.errorprone.annotations.Var;
//
//import java.io.Writer;
//import java.lang.reflect.Type;
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.HashSet;
//import java.util.Iterator;
//import java.util.List;
//import java.util.Map;
//import java.util.Set;
//
//import javax.annotation.processing.AbstractProcessor;
//import javax.annotation.processing.Filer;
//import javax.annotation.processing.Messager;
//import javax.annotation.processing.ProcessingEnvironment;
//import javax.annotation.processing.Processor;
//import javax.annotation.processing.RoundEnvironment;
//import javax.lang.model.SourceVersion;
//import javax.lang.model.element.Element;
//import javax.lang.model.element.ExecutableElement;
//import javax.lang.model.element.TypeElement;
//import javax.lang.model.element.VariableElement;
//import javax.lang.model.type.TypeMirror;
//import javax.tools.Diagnostic;
//import javax.tools.JavaFileObject;

/**
 * 注解处理器，用来生成代码的
 * 使用前需要注册
 */
//@AutoService(Processor.class)  // 注册AutoService。  extends AbstractProcessor
//public class AnnotationsCompiler extends AbstractProcessor {
//    // 1.注解处理器，支持的源码的版本
//    @Override
//    public SourceVersion getSupportedSourceVersion() {
//        return SourceVersion.latestSupported();
//    }
//    // 2.能用来处理哪些注解，找出要处理的注解。
//    @Override
//    public Set<String> getSupportedAnnotationTypes() {
//        Set<String> types = new HashSet<>();
//        types.add(BindView.class.getCanonicalName()); // 自定义的注解BindView.class
////        types.add(Override.class.getCanonicalName());
//        return types;
//    }
//    // 3.定义一个用来生成APT目录下面的文件的对象
//    Filer filer;
//    @Override
//    public synchronized void init(ProcessingEnvironment processingEnvironment) {
//        super.init(processingEnvironment);
//        filer = processingEnvironment.getFiler();
//    }
//
//    /**
//     * 所有的坏事都在这个方法中实现，实现所有的注解处理
//     * javac 编译代码的时候调用的。javac回调process方法。
//     * @param set
//     * @param roundEnvironment
//     * @return
//     */
//    @Override
//    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        // if(set.isEmpty()) return false;  // 优化编译慢的现象。set可能为空。
//        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,"jett---------------"+set); // 打印消息。
//        //获取APP中所有用到了BindView注解的对象, 多个Activity中可能用了这个注解。
//        Set<? extends Element> elementsAnnotatedWith = roundEnvironment.getElementsAnnotatedWith(BindView.class);
//
////        TypeElement//类
////        ExecutableElement//方法
////          VariableElement//属性
//        //开始对elementsAnnotatedWith进行分类，用map来分类存下来。
//        Map<String, List<VariableElement>> map = new HashMap<>();
//        for (Element element : elementsAnnotatedWith) {
//            VariableElement variableElement = (VariableElement) element;
//            String activityName = variableElement.getEnclosingElement().getSimpleName().toString(); // 类元素信息，可以从里面拿到activity名字。
//            Class aClass = variableElement.getEnclosingElement().getClass(); // 拿到类
//
//            List<VariableElement> variableElements = map.get(activityName);
//            if (variableElements == null) { // 第一次进来，新建一个list。
//                variableElements = new ArrayList<>();
//                map.put(activityName, variableElements);
//            }
//            variableElements.add(variableElement);
//        } // 分类完毕，key是activity名字，value是list数组，里面放了多个variableElement
//
//        //开始生成文件，代码示例
////        package com.example.butterknife_framework_demo;
////        import com.example.butterknife_framework_demo.IBinder;
////        public class MainActivity_ViewBinding implements IBinder<com.example.butterknife_framework_demo.MainActivity> {
////            @Override
////            public void bind(com.example.butterknife_framework_demo.MainActivity target) {
////                target.textView = (android.widget.TextView) target.findViewById(2131165359);
////            }
////        } // end 代码示例。

//        if (map.size() > 0) {
//            Writer writer = null;
//            Iterator<String> iterator = map.keySet().iterator();
//            while (iterator.hasNext()) {  // 遍历map
//                String activityName = iterator.next(); // 键：ActivityName
//                List<VariableElement> variableElements = map.get(activityName); // 键对应的值 list
//                //得到包名
//                TypeElement enclosingElement = (TypeElement) variableElements.get(0).getEnclosingElement();
//                String packageName = processingEnv.getElementUtils().getPackageOf(enclosingElement).toString();
//                try {
//                    // 通过filer ，创建文件。文件名：packageName + "." + activityName + "_ViewBinding"，文件在build目录中。
//                    JavaFileObject sourceFile = filer.createSourceFile(packageName + "." + activityName + "_ViewBinding");
//                    writer = sourceFile.openWriter(); // 打开输出流
//                    //        package com.example.dn_butterknife;
//                    writer.write("package " + packageName + ";\n"); // 将字符串写入文件
//                    //        import com.example.dn_butterknife.IBinder;
//                    writer.write("import " + packageName + ".IBinder;\n");
//                    //        public class MainActivity_ViewBinding implements IBinder<
//                    //        com.example.dn_butterknife.MainActivity>{
//                    writer.write("public class " + activityName + "_ViewBinding implements IBinder<" +
//                            packageName + "." + activityName + ">{\n");
//                    //            public void bind(com.example.dn_butterknife.MainActivity target) {
//                    writer.write(" @Override\n" +
//                            " public void bind(" + packageName + "." + activityName + " target){");
//                    //target.tvText=(android.widget.TextView)target.findViewById(2131165325);
//                    // 循环处理所有注解元素。注入可能有多个，用for循环处理。
//                    for (VariableElement variableElement : variableElements) {
//                        //得到名字：tvText
//                        String variableName = variableElement.getSimpleName().toString();
//                        //得到ID：2131165325
//                        int id = variableElement.getAnnotation(BindView.class).value();
//                        //得到类型：eg (android.widget.TextView)
//                        TypeMirror typeMirror = variableElement.asType();
//                        writer.write("target." + variableName + "=(" + typeMirror + ")target.findViewById(" + id + ");\n");
//                    }
//                    writer.write("\n}}");
//
//                } catch (Exception e) {
//                    e.printStackTrace();
//                } finally {
//                    if (writer != null) {
//                        try {
//                            writer.close(); // 关流。
//                        } catch (Exception e) {
//                            e.printStackTrace();
//                        }
//                    }
//                }
//            }
//        }
//        return false;
//    }
//
//}


// target是自己写的IBinder接口，build的时候，来生成接口的实现类。
// 目标文件：app/build/generated/ap_generated_sources/debug/out/com.**.MainActivity_ViewBinding


